﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;

public class UnitLayerObject : ObjectBase
{
    nLayerData _nLayerData = null;

    ZoneRender _ZoneRender = null;

    ICollateStrategy _ICollateStrategy = null;

    nLayerOrder _nLayerOrder = nLayerOrder.Null;

    public UnitLayerObject(ZoneRender zr, nLayerOrder order)
        : base(order.ToString(), ZoneCfg.CameraWorldLayer)
    {
        _ZoneRender = zr;

        _nLayerData = ZoneManager.Instance._ZoneFactory.NewLayerData();

        InitLayerObject();
    }

    public virtual void Serialization(string content)
    {
        if (string.IsNullOrEmpty(content))
        {
            return;
        }

        _nLayerData._ZGD = JsonUtility.FromJson<nZoneLayerGridData>(content);
        for (int i = 0; i < _nLayerData._ZGD.listGd.Count; ++i)
        {
            nZoneGridData zgd = _nLayerData._ZGD.listGd[i];

            nUnitData ud =  ZoneManager.Instance._ZoneMediaManager.GetDataByID(zgd.unitid);

            UnitObject uo = ZoneManager.Instance._ZoneFactory.AddObject(ud);
            uo._Object.transform.position =  BlockFresh._rgc._grids[zgd._GroudOrder];
            uo._GroudOrder = zgd._GroudOrder;

            Push(uo);
        }


        InitLayerObject();

    }

    public virtual string Deserialization()
    {
        Save();

        {
            _nLayerData._ZGD.listGd.Clear();

            for (int i = 0; i < _Foundation.Count; ++i)
            {
                UnitObject uo =((UnitObject)_Foundation[i]);
                nZoneGridData gd = new nZoneGridData();
                gd.unitid = uo._unitData.id;
                gd._GroudOrder = uo._GroudOrder;
                gd._grids_block = BlockFresh.GetRelationGrids(gd._GroudOrder, BlockFresh._rgc._grids[gd._GroudOrder], uo._VBOdata).ToArray();

                _nLayerData._ZGD.listGd.Add(gd);
            }
        }

        UninitLayerObject();

        string sdata = JsonUtility.ToJson(_nLayerData._ZGD, true);

        return sdata;
    }

    /// <summary>
    /// 设置渲染顺序
    /// </summary>
    /// <param name="sorting"></param>
    public override void SetSortingOrder(int sorting)
    {
        //if (_GroudOrder != sorting)
        //    return;

        Order();
    }

    /// <summary>
    /// 设置可见性
    /// </summary>
    /// <param name="visible"></param>
    public override void SetVisible(bool visible)
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ObjectBase ob = (ObjectBase)_Foundation[i];

            ob.SetVisible(visible);
        }
    }

    public override void SetCollate(nLayerOrder order, ICollateStrategy collate)
    {
        _nLayerOrder = order;

        _ICollateStrategy = collate;
    }


    public override void SetColor(Color color)
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ObjectBase ob = (ObjectBase)_Foundation[i];

            ob.SetColor(color);
        }
    }

    public override bool Save()
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ((UnitObject)_Foundation[i]).Save();

        }

        if (BlockFresh != null)
            _nLayerData._grids_block = BlockFresh._grid_blocks;

        return true;
    }

    public override void Unload()
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ObjectBase ob = (ObjectBase)_Foundation[i];
            ob.Unload();
        }
        _Foundation.Clear();

        GameObject.Destroy(_Object);
    }

    public override bool IsSelect(GameObject obj)
    {
        if (!isSelect)
            return false;

        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ObjectBase ob = (ObjectBase)_Foundation[i];

            if (ob._ID == obj.GetInstanceID())
            {
                if (ob.isSelect)
                    return true;
            }
        }

        return false;
    }

    public override ObjectBase Selected(GameObject obj)
    {
        if (!isSelect)
            return null;

        for (int i = 0; i < _Foundation.Count; ++i)
        {
            ObjectBase ob = (ObjectBase)_Foundation[i];

            if (ob._ID == obj.GetInstanceID())
            {
                return ob;
            }
        }

        return null;
    }

    public override void Gizmos(bool flag)
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            UnitObject ob = (UnitObject)_Foundation[i];
            ob._dc.EnableGizmos(flag);
            ob._dc.RefreshRhombus();
        }

    }

    public override void Block(bool flag)
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            UnitObject ob = (UnitObject)_Foundation[i];
            ob._rgc.EnableGizmos(flag);
        }

        BlockFresh._rgc.EnableGizmos(flag);
    }

    #region 操作
    public List<ObjectBase> _Foundation = new List<ObjectBase>();

    public virtual bool Push(UnitObject uo)
    {
        //  如果碰撞 则检测
        if (isLayerCollider)
        {
            if (!BlockFresh.IsCanDone(uo._GroudOrder, uo._VBOdata))
                return false;
        }

        for (int i = 0; i < _Foundation.Count; ++i)
        {
            if (_Foundation[i]._Object.GetInstanceID() == uo._Object.GetInstanceID())
            {
                Update(uo);

                return true;
            }
        }

        //  如果本层内有阻挡限制
        uo._Object.transform.parent = _Object.transform;

        _Foundation.Add(uo);

        Update(uo);

        Order();

        return true;
    }

    public virtual void Update(UnitObject uo)
    {
        if (uo._GroudOrder == -1)
            return;
        
        if (isLayerCollider)
        {
            Vector3 posRhombus = _LayerObject._rgc._grids[uo._GroudOrder];

            List<int> orders = BlockFresh.GetRelationGrids(uo._GroudOrder, posRhombus, uo._VBOdata);

            if (!BlockFresh.IsCanDone(uo._GroudOrder, uo._VBOdata))
                return;

            BlockFresh.SetDone(uo._GroudOrder, uo._VBOdata);
        }

        Vector3 donepos = BlockFresh.GetClosePointRhombus(uo._GroudOrder, uo._VBOdata);
        uo.SetUnitRhombusLeft4World(donepos, uo._GroudOrder);

        if (_ICollateStrategy != null)
            _ICollateStrategy.OBOrder(_nLayerOrder, uo);
    }

    public virtual void Pop(int id_obj)
    {
        for (int i = 0; i < _Foundation.Count; ++i)
        {
            if (id_obj == _Foundation[i]._ID)
            {
                UnitObject uo = (UnitObject)_Foundation[i];
                uo._Object.transform.parent = null;
                uo.Unload();
                uo = null;

                _Foundation.RemoveAt(i);

                break;
            }
        }
    }

    public virtual void PopOrder(int order)
    {

    }

    void Order()
    {
        if (_ICollateStrategy != null)
            _ICollateStrategy.ReOrder(_nLayerOrder, ref _Foundation);
    }

    public void CancelDone(UnitObject uo)
    {
        //  如果碰撞 则检测
        if (isLayerCollider)
        {
            Vector3 posRhombus = _LayerObject._rgc._grids[uo._GroudOrder];

            List<int> orders = BlockFresh.GetRelationGrids(uo._GroudOrder, posRhombus, uo._VBOdata);

            BlockFresh.CancelDone(orders.ToArray());
        }
    }

    public override bool isLayerCollider
    {
        get
        {
            if (_nLayerOrder == nLayerOrder.Wall)
                return false;

            return base.isLayerCollider;
        }
    }
    #endregion

    #region 本层的阻挡
    LayerObject _LayerObject = null;

    public LayerObject BlockFresh
    {
        get
        {
            return _LayerObject;
        }
    }

    void InitLayerObject()
    {
        if (_LayerObject == null)
        {
            _nLayerData._layer_cell_name = _GroudOrder.ToString() + "_Block";
            _LayerObject = new LayerObject(_nLayerData, _Camera_layer);
            _LayerObject.Load();
        }
    }

    void UninitLayerObject()
    {
        if (_LayerObject != null)
            _LayerObject.Unload();
        _LayerObject = null;
    }

    /// <summary>
    /// 获得最近的合法的位置
    /// </summary>
    /// <param name="uo"></param>
    /// <returns></returns>
    int GetNearestOrder(UnitObject uo)
    {
        Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        pos.z = 0;

        uo._Object.transform.position = pos;


        return 0;
    }

    #endregion
}
